package com.fmi.timedealer.achievement;

import java.text.DecimalFormat;
import java.util.ArrayList;

import com.fmi.timedealer.R;
import com.fmi.timedealer.datamanager.IDataManager;
import com.fmi.timedealer.datamanager.SQLiteDataManager;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;

public class AchievementsActivity extends ListActivity {
	
	private static IDataManager dbManager = null;
	private static ArrayList<Achievement> achievements = null;
	private AchievementsAdapter adapter = null;
	public static final int ACTION_REQUEST_CODE = 0;
	public static final int ACTIVITIES_REQUEST_CODE = 1;
	public static final String ACHIEVEMENT_BUNDLE_KEY = "AchievementObject";
	public static final String LEVEL_BUNDLE_KEY = "LevelObject";
	public static final String ACHIEVEMENT_ID_BUNDLE_KEY = "AchievementId";
	public static final String LEVEL_ITEM_BUNDLE_KEY = "LevelItemObject";
	public static final String LEVEL_ID_BUNDLE_KEY = "LevelId";
	private int levelsCount = 0, levelsCompleted = 0;
	
	private static void initDBManager(Activity activity) {
		if (dbManager == null) {
			dbManager = new SQLiteDataManager("MyDB", activity);
			achievements = dbManager.getAchievements();
		}
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.achievements);
		
		initDBManager(this);
		refreshAdapter();
		
	}
	
	@Override
	public void onResume() {
		super.onResume();
		refreshAdapter();
		checkNotCompleted(this);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.achievements_menu, menu);
	    return true;
    }
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		switch (item.getItemId()) {
	        
			case R.id.add_achievement: {
	        	Intent i = new Intent(AchievementsActivity.this, ManageAchievementActivity.class);
				i.putExtra(ACHIEVEMENT_BUNDLE_KEY, new Achievement());
				startActivityForResult(i, ACTION_REQUEST_CODE);
	        	return true;
	        }
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
		menu.setHeaderTitle(achievements.get(info.position).getName());
		
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.manage_achievement, menu);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
	    
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
	    
		switch (item.getItemId()) {
	        case R.id.edit_achievement: {
	        	Intent i = new Intent(AchievementsActivity.this, ManageAchievementActivity.class);
				i.putExtra(ACHIEVEMENT_BUNDLE_KEY, achievements.get(info.position));
				startActivityForResult(i, ACTION_REQUEST_CODE);
	        	return true;
	        }
	        case R.id.delete_achievement: {
	            deleteAchievement(info.position);
	        	return true;
	        }
	        default:
	            return super.onContextItemSelected(item);
	    }
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		if (requestCode == ACTION_REQUEST_CODE) {
			if (resultCode == RESULT_OK) {
				Bundle extras = data.getExtras();
				Achievement achievement = (Achievement)extras.getSerializable(ACHIEVEMENT_BUNDLE_KEY);
				
				updateAchievement(achievement);
			}
		}
	}
	
	private void refreshAdapter() {
		adapter = new AchievementsAdapter(this, R.layout.item_row, achievements);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		setListAdapter(adapter);
		
		ListView lv = getListView();
		registerForContextMenu(lv);
		// On Achievement click
		lv.setOnItemClickListener(new OnItemClickListener() {

			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				Intent i = new Intent(AchievementsActivity.this,
						LevelsActivity.class);
				i.putExtra(ACHIEVEMENT_BUNDLE_KEY, achievements.get(position));
				startActivityForResult(i, ACTIVITIES_REQUEST_CODE);
			}
		});
		adapter.notifyDataSetChanged();
	}
	
	private void updateAchievement(Achievement achievement) {
		
		int position = -1;
		for (int i = 0; i < achievements.size(); i++) {
			if (achievements.get(i).getId() == achievement.getId()) {
				position = i;
				break;
			}
		}
		
		if (position < 0) {
			// Add new object to the collection
			achievements.add(achievement);
		}
		else {
			// Update object 
			achievements.set(position, achievement);
		}
		
		Toast.makeText(this, achievement.getName() + " was successfully saved", Toast.LENGTH_SHORT).show();
	}

	private void deleteAchievement(int position) {
		boolean deleted = dbManager.deleteAchievement(achievements.get(position));
		if (deleted) {
			Achievement deletedAchievement = achievements.get(position);
			achievements.remove(position);
			refreshAdapter();
			Toast.makeText(this, deletedAchievement.getName() + " was successfully deleted", Toast.LENGTH_SHORT).show();
		}
	}
	
	private class AchievementsAdapter extends ArrayAdapter<Achievement> {
		
        private ArrayList<Achievement> items;

        public AchievementsAdapter(Context context, int textViewResourceId, ArrayList<Achievement> items) {
                super(context, textViewResourceId, items);
                this.items = items;
        }
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                
        	View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.item_row, null);
                }
                
                Achievement ach = items.get(position);
                if (ach != null) {
                	TextView tvName = (TextView)v.findViewById(R.id.itemName);
                    TextView tvInfo = (TextView)v.findViewById(R.id.itemInfo);
                    TextView tvStatus = (TextView)v.findViewById(R.id.itemStatus);
                    ProgressBar progressBar = (ProgressBar)v.findViewById(R.id.itemProgressBar);
                    
                    int progress;
                    getLevelInfo(ach);
                    Double ddd = (double) (((double)levelsCompleted / (double)levelsCount) * 100);
                    DecimalFormat twoDForm = new DecimalFormat("#.##");
                    ddd = Double.valueOf(twoDForm.format(ddd));
                    progress = ddd.intValue();
                    
                    progressBar.setProgress((int)progress);
                    
                    if (tvName != null) {
                        tvName.setText(ach.getName());
                    }
                    if (tvInfo != null){
                    	tvInfo.setText("Goal Message: " + ach.getGoalMessage());
                    }
                    if (tvStatus != null) {
                    	tvStatus.setText("Completed levels: " + levelsCompleted + "/" + levelsCount);
                    }
                }
                return v;
        }
	}
	
	private static ArrayList<Achievement> checkAchievementCompleted(ArrayList<Achievement> notCompletedAchievements) {
		ArrayList<Achievement> completed = new ArrayList<Achievement>();
		for (Achievement currAch : notCompletedAchievements) {
			ArrayList<AchievementLevel> levels = dbManager.getLevelsForId(currAch.getId());
			currAch.setLevels(levels);
			currAch.updateCompleted();
			if (currAch.isCompleted()) {
				completed.add(currAch);
				dbManager.updateAchievement(currAch);
			}
		}
		
		return completed;
	}
	
	private static ArrayList<AchievementLevel> checkLevelCompleted(ArrayList<AchievementLevel> notCompletedLevels) {
		ArrayList<AchievementLevel> completedLevels = new ArrayList<AchievementLevel>();
		for (AchievementLevel level : notCompletedLevels) {
			ArrayList<AchievementLevelItem> levelItems = dbManager.getLevelItemsForId(level.getId());
			level.setItems(levelItems);
			level.updateCompleted();
			if (level.isCompleted()) {
				completedLevels.add(level);	
				dbManager.updateLevel(level);
			}	
		}
		
		return completedLevels;
	}
	
	public static void checkNotCompleted(Activity activity) {
		initDBManager(activity);
		ArrayList<AchievementLevelItem> notCompletedLevelItems = dbManager.updateNotCompletedLevelItems();
		ArrayList<AchievementLevelItem> completedItems = new ArrayList<AchievementLevelItem>();
		for (AchievementLevelItem item : notCompletedLevelItems) {
			if (item.isCompleted()) {
				completedItems.add(item);
				dbManager.updateLevelItem(item);
			}
		}
		
		ArrayList<AchievementLevel> notCompletedLevels = dbManager.getLevelsByLevelItems(completedItems);
		ArrayList<AchievementLevel> completedLevels = checkLevelCompleted(notCompletedLevels);
		
		for (AchievementLevel completedLevel : completedLevels) {
			String message = completedLevel.getLevel() + ": " 
					+ completedLevel.getName() + ". " + completedLevel.getGoalMessage();
			showCompleted("You have just advanced to level " + message, "I have just reached level " + message, activity);
		}
		
		ArrayList<Integer> achIds = dbManager.getAchievementIdsForLevels(completedLevels);
		ArrayList<Achievement> notCompletedAchievements = new ArrayList<Achievement>();
		for (Achievement ach : achievements) {
			if (achIds.contains(ach.getId())) {
				notCompletedAchievements.add(ach);
			}
		}
		
		ArrayList<Achievement> completedAchievements = checkAchievementCompleted(notCompletedAchievements);
		for (Achievement completedAchievement : completedAchievements) {
			String message = completedAchievement.getName() + ". " + completedAchievement.getGoalMessage();
			showCompleted("You have just completed your achievement " + message, "I have just completed my achievement " + message, activity);
		}
		
	}
	
	private static void showCompleted(final String message, final String shareMessage, final Activity activity) {
		AlertDialog.Builder builder = new AlertDialog.Builder(activity);
		
    	builder.setMessage(message)
    		.setCancelable(false)
    		.setPositiveButton("Share", new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					Intent shareIntent = new Intent(Intent.ACTION_SEND);
			    	shareIntent.setType("text/plain");
			    	shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareMessage);
			    	activity.startActivity(Intent.createChooser(shareIntent, "Share using"));
			    	dialog.dismiss();
				}
			}).setNegativeButton("Not really", new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					dialog.cancel();
				}
			});
    	AlertDialog alert = builder.create();
    	alert.setTitle("Do you want to share your new achievement?!?");
    	alert.show();
	}
	
	private void getLevelInfo(Achievement achievement) {
		int completed = 0;
		ArrayList<AchievementLevel> levels = dbManager.getLevelsForId(achievement.getId());
		for (AchievementLevel level : levels) {
			if (level.isCompleted()) {
				completed++;
			}
		}
		levelsCompleted = completed;
		levelsCount = levels.size();
	}

}
